package com.tanhua.management.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.management.enums.AgeRangeEnum;
import com.tanhua.management.enums.AreaEnum;
import com.tanhua.management.vo.ParamVo;
import com.tanhua.management.vo.UserDistributionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @Author lenny
 * @create 2021/9/16 21:00
 */
@Service
public class RegisterUserDistributionService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    //抽取公共方法
    private String[] getStrings(UserInfo userInfo) {
        String regex = "-";
        return userInfo.getCity().split(regex);
    }


    /**
     * 拿到注册用户分布信息
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public UserDistributionVo registerUserDistribution(Long startTime, Long endTime) {

        //规定一个日期格式
        //1564821863000 用户1的时间,    1970.1.1月开始....到2019-08-03 16:44:23
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");

        String st = simpleDateFormat.format(new Date(startTime)) + " 00:00:00";
        String et = simpleDateFormat2.format(new Date(endTime)) + " 23:59:59";

        //tb_user_info表拿数据
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();

        //规定一个时间定义域, 范围,.....大于greater than,....小于less than
        //这样,我们就拿到一个 '时间范围' 的查询条件
        queryWrapper.lt("created", et).gt("created", st);

        //去查询,得到 [st,ed] 时间范围内的 UserInfo数据 list表
        List<UserInfo> userInfoList = userInfoMapper.selectList(queryWrapper);

        UserDistributionVo userDistributionVo = new UserDistributionVo();

        //非空判断
        if (CollUtil.isEmpty(userInfoList)) {
            return null;
        }

        //开始统计行业分布情况(从上至下:,性别,行业分布,地区分布,地区合计)
        //1.性别分布
        List<ParamVo> genderDistribution = new ArrayList<>();

        int countMan;
        int countWoman;
        //.count()统计出现次数
        countMan = (int) userInfoList.stream().filter(userInfo -> (SexEnum.MAN).equals(userInfo.getSex())).count();
        countWoman = userInfoList.size() - countMan;

        Collections.addAll(genderDistribution,
                new ParamVo("男性", countMan),
                new ParamVo("女性", countWoman));

        //2.行业分布
        List<ParamVo> industryDistribution = new ArrayList<>();

        int serviceIndustry = (int) userInfoList.stream().filter(userInfo -> "服务".equals(userInfo.getIndustry())).count();
        int manufacturingIndustry = (int) userInfoList.stream().filter(userInfo -> "制造".equals(userInfo.getIndustry())).count();
        int estateIndustry = (int) userInfoList.stream().filter(userInfo -> "地产".equals(userInfo.getIndustry())).count();
        int hotelIndustry = (int) userInfoList.stream().filter(userInfo -> "住宿".equals(userInfo.getIndustry())).count();
        int educationIndustry = (int) userInfoList.stream().filter(userInfo -> "教育".equals(userInfo.getIndustry())).count();
        int foodIndustry = (int) userInfoList.stream().filter(userInfo -> "餐饮".equals(userInfo.getIndustry())).count();

        Collections.addAll(industryDistribution,
                new ParamVo("服务", serviceIndustry),
                new ParamVo("制造", manufacturingIndustry),
                new ParamVo("地产", estateIndustry),
                new ParamVo("住宿", hotelIndustry),
                new ParamVo("教育", educationIndustry),
                new ParamVo("餐饮", foodIndustry));

        //3.地区分布
        List<ParamVo> regionalDistribution = new ArrayList<>();

        //根据"AreaEnum"枚举类来
        //===============华中地区================
        int HUBEI = (int) userInfoList.stream().filter(userInfo -> {
            /*
            北京市-北京城区-东城区
            数据库得知此结构, 取第一个[0]
            */
            String[] split = getStrings(userInfo);
            //startsWith 检测是否以 "xxx" 开头,确保格式正确
            boolean flag = split[0].startsWith(AreaEnum.HUBEI.getProvince());

            //根据true还是false去判断添加还是不添加
            return flag;

        }).count();

        int HENAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.HENAN.getProvince());
        }).count();

        int HUNAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.HUNAN.getProvince());
        }).count();

        //===============华北地区==================
        int SHANXI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.SHANXI.getProvince());
        }).count();

        int HEBEI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.HEBEI.getProvince());
        }).count();

        int BEIJING = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.BEIJING.getProvince());
        }).count();

        int TIANJIN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.TIANJIN.getProvince());
        }).count();

        int NEIMENGGU = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.NEIMENGGU.getProvince());
        }).count();

        //=============华东地区================
        int ZHEJIANG = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.ZHEJIANG.getProvince());
        }).count();

        int JIANGSU = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.JIANGSU.getProvince());
        }).count();

        int SHANGHAI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.SHANGHAI.getProvince());
        }).count();

        int ANHUI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.ANHUI.getProvince());
        }).count();

        int JIANGXI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.JIANGXI.getProvince());
        }).count();

        int SHANDONG = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.SHANDONG.getProvince());
        }).count();

        int FUJIAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.FUJIAN.getProvince());
        }).count();

        int TAIWAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.TAIWAN.getProvince());
        }).count();


        //=============华南地区================
        int GUANGXI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.GUANGXI.getProvince());
        }).count();

        int GUANGDONG = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.GUANGDONG.getProvince());
        }).count();

        int HAINAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.HAINAN.getProvince());
        }).count();

        int HONGKONG = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.HONGKONG.getProvince());
        }).count();

        int MACAO = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.MACAO.getProvince());
        }).count();


        //=============西北地区================

        int QINGHAI = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.QINGHAI.getProvince());
        }).count();

        int NINGXIA = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.NINGXIA.getProvince());
        }).count();

        int SHANXI2 = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.SHANXI2.getProvince());
        }).count();

        int GANSU = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.GANSU.getProvince());
        }).count();

        int XINJIANG = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.XINJIANG.getProvince());
        }).count();


        //=============东北地区================
        int JILIN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.JILIN.getProvince());
        }).count();

        int HEILONGJIANG = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.HEILONGJIANG.getProvince());
        }).count();


        int LIAONING = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.LIAONING.getProvince());
        }).count();

        //=============西南地区================
        int GUIZHOU = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.GUIZHOU.getProvince());
        }).count();

        int YUNNAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.YUNNAN.getProvince());
        }).count();

        int CHONGQING = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.CHONGQING.getProvince());
        }).count();

        int SICHUAN = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.SICHUAN.getProvince());
        }).count();

        int TIBET = (int) userInfoList.stream().filter(userInfo -> {
            String[] split = getStrings(userInfo);
            return split[0].startsWith(AreaEnum.TIBET.getProvince());
        }).count();


        Collections.addAll(regionalDistribution,
                //====================华中======================
                new ParamVo(AreaEnum.HUBEI.getProvince(), HUBEI),
                new ParamVo(AreaEnum.HUNAN.getProvince(), HUNAN),
                new ParamVo(AreaEnum.HENAN.getProvince(), HENAN),
                //====================华北======================
                new ParamVo(AreaEnum.SHANXI.getProvince(), SHANXI),
                new ParamVo(AreaEnum.HEBEI.getProvince(), HEBEI),
                new ParamVo(AreaEnum.BEIJING.getProvince(), BEIJING),
                new ParamVo(AreaEnum.TIANJIN.getProvince(), TIANJIN),
                new ParamVo(AreaEnum.NEIMENGGU.getProvince(), NEIMENGGU),
                //====================华东======================
                new ParamVo(AreaEnum.ZHEJIANG.getProvince(), ZHEJIANG),
                new ParamVo(AreaEnum.JIANGSU.getProvince(), JIANGSU),
                new ParamVo(AreaEnum.SHANGHAI.getProvince(), SHANGHAI),
                new ParamVo(AreaEnum.ANHUI.getProvince(), ANHUI),
                new ParamVo(AreaEnum.JIANGXI.getProvince(), JIANGXI),
                new ParamVo(AreaEnum.SHANDONG.getProvince(), SHANDONG),
                new ParamVo(AreaEnum.TAIWAN.getProvince(), TAIWAN),
                new ParamVo(AreaEnum.FUJIAN.getProvince(), FUJIAN),
                //====================华南======================
                new ParamVo(AreaEnum.GUANGXI.getProvince(), GUANGXI),
                new ParamVo(AreaEnum.GUANGDONG.getProvince(), GUANGDONG),
                new ParamVo(AreaEnum.HAINAN.getProvince(), HAINAN),
                new ParamVo(AreaEnum.HONGKONG.getProvince(), HONGKONG),
                new ParamVo(AreaEnum.MACAO.getProvince(), MACAO),
                //====================西北======================
                new ParamVo(AreaEnum.QINGHAI.getProvince(), QINGHAI),
                new ParamVo(AreaEnum.NINGXIA.getProvince(), NINGXIA),
                new ParamVo(AreaEnum.SHANXI2.getProvince(), SHANXI2),
                new ParamVo(AreaEnum.GANSU.getProvince(), GANSU),
                new ParamVo(AreaEnum.XINJIANG.getProvince(), XINJIANG),
                //=============东北地区================
                new ParamVo(AreaEnum.HEILONGJIANG.getProvince(), HEILONGJIANG),
                new ParamVo(AreaEnum.JILIN.getProvince(), JILIN),
                new ParamVo(AreaEnum.LIAONING.getProvince(), LIAONING),
                //=============西南地区================
                new ParamVo(AreaEnum.GUIZHOU.getProvince(), GUIZHOU),
                new ParamVo(AreaEnum.YUNNAN.getProvince(), YUNNAN),
                new ParamVo(AreaEnum.CHONGQING.getProvince(), CHONGQING),
                new ParamVo(AreaEnum.SICHUAN.getProvince(), SICHUAN),
                new ParamVo(AreaEnum.TIBET.getProvince(), TIBET)

        );
        //4.地区合计,拿到各地区数量,累加
        List<ParamVo> regionalTotal = new ArrayList<>();

        int HUAZHONG = regionalDistribution.get(0).getAmount() + regionalDistribution.get(1).getAmount() + regionalDistribution.get(2).getAmount();

        int HUABEI = regionalDistribution.get(3).getAmount() + regionalDistribution.get(4).getAmount() + regionalDistribution.get(5).getAmount()
                + regionalDistribution.get(6).getAmount();

        int HUADONG = regionalDistribution.get(8).getAmount() + regionalDistribution.get(9).getAmount() + regionalDistribution.get(10).getAmount()
                + regionalDistribution.get(11).getAmount() + regionalDistribution.get(12).getAmount() + regionalDistribution.get(13).getAmount()
                + regionalDistribution.get(14).getAmount() + regionalDistribution.get(15).getAmount();

        int HUANAN = regionalDistribution.get(16).getAmount() + regionalDistribution.get(17).getAmount() + regionalDistribution.get(18).getAmount()
                + regionalDistribution.get(19).getAmount() + regionalDistribution.get(20).getAmount();

        int XIBEI = regionalDistribution.get(21).getAmount() + regionalDistribution.get(22).getAmount() + regionalDistribution.get(23).getAmount()
                + regionalDistribution.get(24).getAmount() + regionalDistribution.get(25).getAmount();

        int DONGBEI = regionalDistribution.get(26).getAmount() + regionalDistribution.get(27).getAmount() + regionalDistribution.get(28).getAmount();

        int XINAN = regionalDistribution.get(29).getAmount() + regionalDistribution.get(30).getAmount() + regionalDistribution.get(31).getAmount()
                + regionalDistribution.get(32).getAmount() + regionalDistribution.get(33).getAmount();

        Collections.addAll(regionalTotal,
                new ParamVo("华中地区", HUAZHONG),
                new ParamVo("华北地区", HUABEI),
                new ParamVo("华东地区", HUADONG),
                new ParamVo("华南地区", HUANAN),
                new ParamVo("西北地区", XIBEI),
                new ParamVo("东北地区", DONGBEI),
                new ParamVo("西南地区", XINAN)
        );

        //5.年龄分布
        List<ParamVo> ageDistribution = new ArrayList<>();
        int L1 = (int) userInfoList.stream().filter(userInfo -> {
            return userInfo.getAge() > 0 && userInfo.getAge() < 18;
        }).count();

        int L2 = (int) userInfoList.stream().filter(userInfo -> {
            return userInfo.getAge() >= 18 && userInfo.getAge() < 24;
        }).count();

        int L3 = (int) userInfoList.stream().filter(userInfo -> {
            return userInfo.getAge() >= 24 && userInfo.getAge() < 31;
        }).count();

        int L4 = (int) userInfoList.stream().filter(userInfo -> {
            return userInfo.getAge() >= 31 && userInfo.getAge() < 41;
        }).count();

        int L5 = (int) userInfoList.stream().filter(userInfo -> {
            return userInfo.getAge() >= 41 && userInfo.getAge() < 50;
        }).count();

        int L6 = (int) userInfoList.stream().filter(userInfo -> {
            return userInfo.getAge() >= 50;
        }).count();


        Collections.addAll(ageDistribution,
                new ParamVo(AgeRangeEnum.stage0_17.getDesc(), L1),
                new ParamVo(AgeRangeEnum.stage18_23.getDesc(), L2),
                new ParamVo(AgeRangeEnum.stage24_30.getDesc(), L3),
                new ParamVo(AgeRangeEnum.stage31_40.getDesc(), L4),
                new ParamVo(AgeRangeEnum.stage41_50.getDesc(), L5),
                new ParamVo(AgeRangeEnum.stage50Plus.getDesc(), L6));


        //行业分布top10
        userDistributionVo.setIndustryDistribution(industryDistribution);
        //年龄分布
        userDistributionVo.setAgeDistribution(ageDistribution);
        //性别分布
        userDistributionVo.setGenderDistribution(genderDistribution);
        //地区分布
        userDistributionVo.setLocalDistribution(regionalDistribution);
        //地区合计
        userDistributionVo.setLocalTotal(regionalTotal);

        return userDistributionVo;
    }
}
